﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;

namespace DotNETX.Version.IniVersionInfo
{
    public class VersionInfoUtils
    {
        public const string DEFAULT_VERSION_INI_FILE = "version.ini";

        public static VersionInfo ReadVersionInfo(string file)
        {
            string strVersion = ReadValue(file, "VersionInfo", "version");
            string strDate = ReadValue(file, "VersionInfo", "date");
            string strDes = ReadValue(file, "VersionInfo", "description");

            VersionInfo info = new VersionInfo();
            info.VersionName = strVersion;
            DateTime d;
            if (DateTime.TryParse(strDate, out d))
            {
                info.ReleaseDate = d;
            }
            info.Description = strDes;

            return info;
        }

        public static void WriteVersionInfo(string file, VersionInfo versionInfo)
        {
            WritueValue(file, "VersionInfo", "version", versionInfo.VersionName);
            WritueValue(file, "VersionInfo", "date", versionInfo.ReleaseDate.ToString("yyyy-MM-dd HH:mm:ss"));
            WritueValue(file, "VersionInfo", "description", versionInfo.Description);
        }

        public static string LocateVersionIni(Type type, string configPath)
        {
            return TryLocateFile(type, configPath, DEFAULT_VERSION_INI_FILE);
        }

        private static string TryLocateFile(Type type, string tryfile, string deffile)
        {
            string asmPath = type.Assembly.Location;
            string asmFolder = asmPath.Substring(0, asmPath.LastIndexOf('\\') + 1);
            string appFolder = AppDomain.CurrentDomain.BaseDirectory + "\\";
            string t = null;
            if (null != tryfile)
            {
                if (tryfile.Contains(':') && System.IO.File.Exists(tryfile)) return tryfile;
                else
                {
                    t = System.IO.Path.Combine(asmFolder + tryfile);
                    if (System.IO.File.Exists(t)) return t;
                    t = System.IO.Path.Combine(appFolder + tryfile);
                    if (System.IO.File.Exists(t)) return t;
                }
            }

            t = System.IO.Path.Combine(asmFolder + deffile);
            if (System.IO.File.Exists(t)) return t;
            t = System.IO.Path.Combine(appFolder + deffile);
            if (System.IO.File.Exists(t)) return t;
            return null;
        }

        #region ini rw api

        // 声明INI文件的写操作函数 WritePrivateProfileString()
        [System.Runtime.InteropServices.DllImport("kernel32")]
        private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
        // 声明INI文件的读操作函数 GetPrivateProfileString()
        [System.Runtime.InteropServices.DllImport("kernel32")]
        private static extern int GetPrivateProfileString(string section, string key, string def, System.Text.StringBuilder retVal, int size, string filePath);

        private static void WritueValue(string sPath, string section, string key, string value)
        {
            // section=配置节，key=键名，value=键值，path=路径
            WritePrivateProfileString(section, key, value, sPath);
        }
        private static string ReadValue(string sPath, string section, string key)
        {
            // 每次从ini中读取多少字节
            System.Text.StringBuilder temp = new System.Text.StringBuilder(255);
            // section=配置节，key=键名，temp=上面，path=路径
            GetPrivateProfileString(section, key, "", temp, 255, sPath);
            return temp.ToString();
        }

        #endregion
    }
}
